package com.xmlt.ui.editors.browsereditor;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.w3c.dom.Document;

import com.xmlt.core.template.TemplateException;
import com.xmlt.core.template.TemplateManager;
import com.xmlt.core.template.instance.AbstractInstance;
import com.xmlt.core.template.instance.Instance;
import com.xmlt.core.template.instance.MultiInstance;
import com.xmlt.core.template.instance.Value;
import com.xmlt.ui.builder.BuilderPlugin;
import com.xmlt.ui.editors.EditorsPlugin;
import com.xmlt.ui.xmltutils.GuidedDisplayGenerator;

public class TemplateInstanceEditor extends BrowserEditor {

	private TemplateManager manager;
	private Instance instance;
	private String ref;
	private TemplateException te;

	/**
	 * Creates a multi-page editor example.
	 */
	public TemplateInstanceEditor() {
		ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
	}
	
	@Override
	protected String getURL() {
		return EditorsPlugin.getResourceURL("site/instance.html");
	}

	@Override
	public Document getEditedDocument() {
		return instance.getDocument();
	}

	/**
	 * Creates page 0 of the multi-page editor, which contains a text editor.
	 */
	protected void addCustomfunctions() {
		new MessengerFunction("setFieldInJava") {
			@Override
			public Object function(Object[] arguments) {
				try {
					String id = (String) arguments[0];
					String value = (String) arguments[1];
					Object obj = instance.lookup(id);
					if (obj instanceof Value) {
						((Value) obj).setValue(value);
						setDirty(true);
						boolean result = ((Value) obj).validate();
						Display.getDefault().asyncExec(new Runnable() {

							@Override
							public void run() {
								refresh();
							}
						});
						return result;
					}
				} catch (Exception e) {
					return e;
				}
				return false;
			}
		};
		new MessengerFunction("addListItemJava") {
			@Override
			public Object function(Object[] arguments) {
				String id = (String) arguments[0];
				try {
					AbstractInstance ins = instance.lookup(id);
					if (ins instanceof MultiInstance) {
						((MultiInstance) ins).addItem();
						setBrowserContent();
						setDirty(true);
						return true;
					}
				} catch (TemplateException e) {
					return true;
				}
				return false;
			}
		};
		new MessengerFunction("delListItemJava") {
			@Override
			public Object function(Object[] arguments) {
				String id = (String) arguments[0];
				AbstractInstance ins = instance.lookup(id);
				if (ins.getParent() != null && ins.getParent() instanceof MultiInstance) {
					((MultiInstance) ins.getParent()).deleteItem(getIndex(id));
					setBrowserContent();
					setDirty(true);
					return true;
				}
				return false;
			}
		};
	}


	/**
	 * The <code>MultiPageEditorPart</code> implementation of this
	 * <code>IWorkbenchPart</code> method disposes all nested editors.
	 * Subclasses may extend.
	 */
	public void dispose() {
		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
		super.dispose();
	}

	/**
	 * Saves the multi-page editor's document.
	 */
	public void doSave(IProgressMonitor monitor) {
		manager.getResolver().save(instance.getDocument(), ref, true);
		setDirty(false);
		firePropertyChange(PROP_DIRTY);
	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		super.init(site, input);
	}

	@Override
	public String getContent() {
		IFile file = (IFile) getEditorInput().getAdapter(IFile.class);
		manager = BuilderPlugin.getTemplateManager(file.getProject());
		ref = file.getProjectRelativePath().toString();
		try {
			instance = manager.loadInstance(ref);
		} catch (TemplateException e) {
			te = e;
		}
		if (instance == null) {
			String msg = "";
			if (te != null) {
				msg = te.getMessage();
			}
			
			return "Could not load the instance: " + msg;
		}
		try {
			String content = new GuidedDisplayGenerator().getDisplayString(instance);
			return content;
		} catch (Exception e) {
			return e.getMessage();
		}
	}

	@Override
	public void setContent(String c) {
	}

	/*private String getInstancePath(String s) {
		return s.substring(0, s.lastIndexOf("["));
	}*/

	private int getIndex(String s) {
		String last = s.substring(s.lastIndexOf("["));
		return Integer.parseInt(last.substring(1, last.length() - 1));
	}
}
